﻿/*------------------------------------------------------------------------

PRESERVE.HPP v3.11.14

Copyright 楊志賢 CxxlMan, 2008 - 2014
All Rights Reserved

儲存結構規範

root---第一個物件
     |......
     |
     |-第二個物件---子物件
     |            |-子物件
     |            |....
     |            |
     |            |-屬性資料
     |            |-屬性資料
     |            |....
     |....
     |-最後一個物件

第一層的名稱不可重複，第二層子物件在前，屬性在後，名稱可重複，但對應要正
確，即存取的順序要一致

------------------------------------------------------------------------*/
#if !defined(__PRESERVE_HPP_CxxlMan)
#define __PRESERVE_HPP_CxxlMan

#include <list>
// #include "CENTRALIZEDMGR.HPP"
#include <CXXLLIST.HPP>
#include <SLIST.HPP>
#include "SMART_STRING.HPP"
#include "PRESERVECOMMON.HPP"

class CentralizedMgr;

namespace CxxlMan
{

class _Sets;
class cxxlPreserve;
class Filter;
class SaveFilter;
class LoadFilter;
class IPreserve2Storage;
class cxxlPreserve2;
class IcxxlStorage;
extern CXXLPRESERVE_DLLEXPORT REGENERARETURN_TYPE cxxlFASTCALL cxxlCM_Regenera(Smart_Ptr<cxxlPreserve2> &P2_Ret, const UNICODE_String &Name, const Smart_Ptr<IcxxlStorage> &IcxxlStorage_Arg, bool isRestore);

/*
** 儲存體抽象類別
*/
class CXXLPRESERVE_DLLEXPORT IcxxlStorage:virtual public cxxlObject
{

  virtual bool cxxlFASTCALL toSave(cxxlPreserve *v, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL toLoad(cxxlPreserve *v, const UNICODE_String &Name) = 0;

  virtual Smart_Ptr<IPreserve2Storage> cxxlFASTCALL GetIPreserve2Storage(const UNICODE_String &Name) = 0;

protected:
  // 不管有幾個 Storage 都使用同一個 CriticalSec
  static CriticalSec csObject;

public:
  IcxxlStorage(ISpirit *spirit = Spirit_Easy)  // Constructor
    :cxxlObject(spirit)
  {}
  virtual ~IcxxlStorage(){} // Destruciro

  // 成功回報 true
  // 失敗回報 false
  // 失敗原因可能是 Name 已存在、原 Name 中的資料不會被變動。
  template<typename T> bool cxxlFASTCALL Save(const Smart_Ptr<T> &v, const UNICODE_String &Name)
  {
    T *V = v;
    return toSave(V, Name);
  }

  // 成功回報 true
  // 失敗回報 false
  // 失敗原因可能是 Name 不存在、存取順序不一致，或物件(或子孫物件)已
  // 被更換過而無法和永存資料對應
  template<typename T> bool cxxlFASTCALL Load(const Smart_Ptr<T> &v, const UNICODE_String &Name)
  {
    T *V = v;
    return toLoad(V, Name);
  }

  // 刪除指定名稱的永續儲存資料
  virtual bool cxxlFASTCALL Delete(const UNICODE_String &Name) = 0;

  friend CXXLPRESERVE_DLLEXPORT REGENERARETURN_TYPE cxxlFASTCALL cxxlCM_Regenera(Smart_Ptr<cxxlPreserve2> &P2_Ret, const UNICODE_String &Name, const Smart_Ptr<IcxxlStorage> &IcxxlStorage_Arg, bool isRestore);
};


/*
** 具有永續儲存能力的物件所須繼承的介面
*/
class CXXLPRESERVE_DLLEXPORT cxxlPreserve:virtual public cxxlObject
{

  // 記錄所有的 cxxlPreserve 子物件
  _Sets *_Sets_List;

  // 記錄處理進程
  //   1. 若是 0，才會被 SaveFilter/LoadFilter 的 Constructor 處理，處理後為 1
  //   2. 若是 1 且有被 LoadFilter 的 Load() 功能處理過會由 1 變成 2
  //   3. 不管所有 cxxlPreserve 處理的結果是否成功，最後都得回歸為 0
  char Transaction;



protected:

  // 儲存容器藉此取得要永續存取的屬性資料
  // 延伸類別須以 virtual 的形式覆寫
  // 並且須呼叫上層類別的此函數
  virtual bool cxxlFASTCALL Ref(Filter *F) = 0;

  // Preserve 的延伸類別都要使用
  CriticalSec csPreserve;

public:
  // Constructor
  cxxlPreserve()
    :cxxlObject(Spirit_Easy)
  {
    _Sets_List = NULL;
    Transaction = 0;
  }

  // Destructor
  virtual ~cxxlPreserve()
  {
  }

  friend class SaveFilter;
  friend class LoadFilter;
  friend class _Sets;
  friend class ::CentralizedMgr;
};


class CXXLPRESERVE_DLLEXPORT _Sets
{
  UNICODE_String m_Name;
  _Sets *Next;

  const _Sets * cxxlFASTCALL GetNextSets() const
  {
    return Next;
  }


  UNICODE_String cxxlFASTCALL GetName() const
  {
    return m_Name;
  }

  virtual Smart_Ptr<cxxlList<cxxlPreserve> > cxxlFASTCALL GetPreserveList() const = 0 ;

  virtual REGENERARETURN_TYPE cxxlFASTCALL PutPreserve2(const Smart_Ptr<cxxlPreserve2> &Preserve2_Arg);

  virtual REGENERARETURN_TYPE cxxlFASTCALL PutEmptyPreserve2();


public:
  _Sets(cxxlPreserve *Host, const UNICODE_String &Name_Arg)
  {
    m_Name = Name_Arg;
    Next = Host->_Sets_List;
    Host->_Sets_List = this;
  }

  friend class SaveFilter;
  friend class LoadFilter;
  friend class ::CentralizedMgr;
};

/*
** 只能作為 cxxlPreserve 的成員函數之用
*/
template <typename T>
class PSmart_Ptr:public Smart_Ptr<cxxlPreserve>, public _Sets
{
  T *m_pObj;

  virtual Smart_Ptr<cxxlList<cxxlPreserve> > cxxlFASTCALL GetPreserveList() const
  {
    Smart_Ptr<cxxlList<cxxlPreserve> > cxxlPreserve_List = new cxxlList<cxxlPreserve>;
    if(m_pObj)
      cxxlPreserve_List->Push_Back(m_pObj);
    return cxxlPreserve_List;
  }


public:
  // Destructor
  virtual ~PSmart_Ptr()
  {
  }

  // Constructor
  PSmart_Ptr(T *pObj,cxxlPreserve *Host,const UNICODE_String &Name_Arg)
    :Smart_Ptr<cxxlPreserve>(pObj, Host), _Sets(Host, Name_Arg)
  {
    m_pObj = pObj;
  }

  // 設定函數
  PSmart_Ptr &cxxlFASTCALL operator=(T *pObj)
  {
    m_pObj = pObj;

    Smart_Ptr<cxxlPreserve>::operator =(pObj);
    return *this;
  }

  // Copy 函數
  PSmart_Ptr &cxxlFASTCALL operator=(const PSmart_Ptr &Src)
  {
    m_pObj = Src.m_pObj;

    Smart_Ptr<cxxlPreserve>::operator =(Src);
    return *this;
  }

  T *cxxlFASTCALL operator->() const
  {
    return m_pObj;
  }

  cxxlFASTCALL operator T*() const
  {
    return m_pObj;
  }

  // 放棄持有的物件(包裹的物件成為 NULL)
  void cxxlFASTCALL Destroy()
  {
    Smart_Ptr<cxxlPreserve>::Destroy();
    m_pObj = NULL;
  }

};

/*
** 只能作為 cxxlPreserve 的成員函數之用
*/
template <typename T>
class PSmart_Set:private Smart_Ptr<cxxlObject>, public _Sets
{

  SList<T,false> *m_pSetList;

  virtual Smart_Ptr<cxxlList<cxxlPreserve> > cxxlFASTCALL GetPreserveList() const
  {
    Smart_Ptr<cxxlList<cxxlPreserve> > cxxlPreserve_List = new cxxlList<cxxlPreserve>;

    Smart_Ptr<cxxlList<T> > tmp_List = m_pSetList->cxxlList_Create();
    tmp_List->ResetPT(toHead);
    unsigned long Count = tmp_List->GetCount();
    for(Smart_Ptr<T> tmp_Ptr = (*tmp_List)++; Count; --Count,tmp_Ptr = (*tmp_List)++)
      cxxlPreserve_List->Push_Back((T*)tmp_Ptr);

    return cxxlPreserve_List;
  }


public:
  // Destructor
  virtual ~PSmart_Set()
  {
    delete m_pSetList;
  }

  // Constructor
  PSmart_Set(cxxlPreserve *Host,const UNICODE_String &Name_Arg)
    :Smart_Ptr<cxxlObject>((m_pSetList = new SList<T,false>), Host),
     _Sets(Host, Name_Arg)
  {
    m_pSetList = new SList<T,false>;
  }

  // 加入一個子物件
  void cxxlFASTCALL Add(const Smart_Ptr<T> &addObj)
  {
    m_pSetList->Push_Back(addObj);
  }

  // 移除指定的子物件
  void cxxlFASTCALL Delete(const Smart_Ptr<T> &delObj)
  {
    m_pSetList->Delete(delObj);
  }

  // 取得所有子物件
  Smart_Ptr<cxxlList<T> > cxxlFASTCALL GetList() const
  {
    return m_pSetList->cxxlList_Create();
  }

  // 取得子物件的數目
  unsigned long cxxlFASTCALL GetCount() const
  {
    return m_pSetList->GetCount();
  }

  // 放棄所有的子物件
  void cxxlFASTCALL Destroy()
  {
    m_pSetList->ClearAll();
  }

};


class Filter:virtual public cxxlObject
{
public:
  // Constructor
  Filter(ISpirit *spirit)
    :cxxlObject(spirit)
  {

  }
  virtual ~Filter(){}  // Destructor

  // 支援以下這些基本形別的永緒儲存
  // 由 SaveFilter 和 LoadFilter 實作
  // 只有在 LoadFilter 的讀取檢查階段才會拿 Count 和 Name 和儲存的資料比對，並回覆檢查是否正確
  // 其他回覆值皆為 true
  virtual bool cxxlFASTCALL Ref(const bool *Src, size_t Count, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL Ref(const char *Src, size_t Count, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL Ref(const short *Src, size_t Count, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL Ref(const int *Src, size_t Count, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL Ref(const long *Src, size_t Count, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL Ref(const wchar_t *Src, size_t Count, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL Ref(const unsigned char *Src, size_t Count, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL Ref(const unsigned short *Src, size_t Count, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL Ref(const unsigned int *Src, size_t Count, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL Ref(const unsigned long *Src, size_t Count, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL Ref(const float *Src, size_t Count, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL Ref(const double *Src, size_t Count, const UNICODE_String &Name) = 0;
};

/*
** 負責將被儲存體要保存的資料存起來
*/
class SaveFilter:public Filter
{
protected:
  void cxxlFASTCALL SetTransaction(cxxlPreserve *v,int Transaction) const
  {
    v->Transaction = Transaction;
  }

  int cxxlFASTCALL GetTransaction(cxxlPreserve *v) const
  {
    return v->Transaction;
  }

  _Sets *cxxlFASTCALL Get_Sets_List(cxxlPreserve *v) const
  {
    return v->_Sets_List;
  }

  void cxxlFASTCALL Lock(cxxlPreserve *v) const
  {
    v->csPreserve.Enter();
  }

  void cxxlFASTCALL UnLock(cxxlPreserve *v) const
  {
    v->csPreserve.Leave();
  }

  bool cxxlFASTCALL Save(cxxlPreserve *v)
  {
    return v->Ref(this);
  }

  const _Sets * cxxlFASTCALL Next_Sets(const _Sets *p) const
  {
    return p->GetNextSets();
  }

  Smart_Ptr<cxxlList<cxxlPreserve> > cxxlFASTCALL GetPreserveList(const _Sets *p) const
  {
    return p->GetPreserveList();
  }

  UNICODE_String cxxlFASTCALL GetName(const _Sets *p) const
  {
    return p->GetName();
  }


public:
  // Constructor
  SaveFilter(ISpirit *spirit)
    :cxxlObject(spirit),Filter(spirit)
  {

  }
  virtual ~SaveFilter(){}  // Destructor

};

/*
** 負責取回被儲存體保存的資料
*/
class LoadFilter:public Filter
{
protected:
  void cxxlFASTCALL SetTransaction(cxxlPreserve *v,int Transaction) const
  {
    v->Transaction = Transaction;
  }

  int cxxlFASTCALL GetTransaction(cxxlPreserve *v) const
  {
    return v->Transaction;
  }

  _Sets *cxxlFASTCALL Get_Sets_List(cxxlPreserve *v) const
  {
    return v->_Sets_List;
  }

  void cxxlFASTCALL Lock(cxxlPreserve *v) const
  {
    v->csPreserve.Enter();
  }

  void cxxlFASTCALL UnLock(cxxlPreserve *v) const
  {
    v->csPreserve.Leave();
  }

  bool cxxlFASTCALL Load(cxxlPreserve *v)
  {
    return v->Ref(this);
  }

  void cxxlFASTCALL Commit(cxxlPreserve *v,bool r)
  {
    if(r)
      v->Ref(this);
    else
      v->Ref(NULL);
  }

  const _Sets * cxxlFASTCALL Next_Sets(const _Sets *p) const
  {
    return p->GetNextSets();
  }

  Smart_Ptr<cxxlList<cxxlPreserve> > cxxlFASTCALL GetPreserveList(const _Sets *p) const
  {
    return p->GetPreserveList();
  }

  UNICODE_String cxxlFASTCALL GetName(const _Sets *p) const
  {
    return p->GetName();
  }




public:
  // Constructor
  LoadFilter(ISpirit *spirit)
    :cxxlObject(spirit),Filter(spirit)
  {
  }
  virtual ~LoadFilter(){}  // Destructor

  // 在讀取檢查階段才可以用以下這些函數取得資料的實際位置及 Count，
  // 這些函數只檢查 Name 和在儲存的資料是否一致
  virtual bool cxxlFASTCALL LoadChk(const bool **v, size_t *Count, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL LoadChk(const char **v, size_t *Count, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL LoadChk(const short **v, size_t *Count, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL LoadChk(const int **v, size_t *Count, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL LoadChk(const long **v, size_t *Count, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL LoadChk(const wchar_t **v, size_t *Count, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL LoadChk(const unsigned char **v, size_t *Count, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL LoadChk(const unsigned short **v, size_t *Count, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL LoadChk(const unsigned int **v, size_t *Count, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL LoadChk(const unsigned long **v, size_t *Count, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL LoadChk(const float **v, size_t *Count, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL LoadChk(const double **v, size_t *Count, const UNICODE_String &Name) = 0;

  // 可同時用於檢查和實際讀取兩階段
  // 在檢查階段只檢查 Name 和在儲存的資料是否一致
  // 實際讀取階段會將 *v 刪掉，替換為讀取的資料位址
  virtual bool cxxlFASTCALL LoadRef(const bool **v, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL LoadRef(const char **v, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL LoadRef(const short **v, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL LoadRef(const int **v, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL LoadRef(const long **v, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL LoadRef(const wchar_t **v, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL LoadRef(const unsigned char **v, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL LoadRef(const unsigned short **v, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL LoadRef(const unsigned int **v, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL LoadRef(const unsigned long **v, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL LoadRef(const float **v, const UNICODE_String &Name) = 0;
  virtual bool cxxlFASTCALL LoadRef(const double **v, const UNICODE_String &Name) = 0;

  // 是否在檢查階段
  virtual bool isChk() const = 0;
};



}   /* namespace CxxlMan */
#endif
